package com.open.capacity.employee.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.open.capacity.common.annotation.ApiIdempotent;
import com.open.capacity.common.auth.details.LoginAppUser;
import com.open.capacity.common.exception.controller.ControllerException;
import com.open.capacity.common.exception.service.ServiceException;
import com.open.capacity.common.model.SysUser;
import com.open.capacity.common.util.SysUserUtil;
import com.open.capacity.common.web.PageResult;
import com.open.capacity.common.web.Result;
import com.open.capacity.employee.model.EmployeeModel;
import com.open.capacity.employee.service.ConcurrentService;
import com.open.capacity.log.annotation.LogAnnotation;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

@Slf4j

@RestController
@RequestMapping("/concurrent")
@Api(tags = "兼职人员")
public class ConcurrentController {

    @Autowired
    private ConcurrentService concurrentService;

    /**
     * 当前登录兼职人员 LoginAppUser
     *
     * @return
     * @throws ControllerException
     * @throws JsonProcessingException
     */
    @ApiOperation(value = "根据access_token当前登录人员")
    @GetMapping("/concurrent/current")
    @LogAnnotation(module = "employee-center", recordRequestParam = false)
    public LoginAppUser getLoginAppUser() throws ControllerException {
        try {
            LoginAppUser loginUser = SysUserUtil.getLoginAppUser();
            return loginUser;
        } catch (Exception e) {
            throw new ControllerException(e);
        }
    }

//    @GetMapping(value = "/concurrent-anon/login", params = "username")
//    @ApiOperation(value = "根据兼职人员名查询兼职人员")
//    @LogAnnotation(module = "employee-center", recordRequestParam = false)
//    public LoginAppUser findByUsername(String username) throws ControllerException {
//        try {
//            return concurrentService.findByUsername(username);
//        } catch (ServiceException e) {
//            throw new ControllerException(e);
//        }
//    }


//    @GetMapping(value = "/concurrent-anon/mobile", params = "mobile")
//    @ApiOperation(value = "根据兼职人员名查询手机号")
//    @LogAnnotation(module = "employee-center", recordRequestParam = false)
//    public LoginAppUser findByMobile(String mobile) throws ControllerException {
//        try {
//            return concurrentService.findByMobile(mobile);
//        } catch (ServiceException e) {
//            throw new ControllerException(e);
//        }
//    }

    @PreAuthorize("hasAuthority('user:get/concurrent/{id}')")
    @GetMapping("/concurrent/{id}")
    @LogAnnotation(module = "employee-center", recordRequestParam = false)
    public SysUser findUserById(@PathVariable Long id) throws ControllerException {
        try {
            return concurrentService.findById(id);
        } catch (ServiceException e) {
            throw new ControllerException(e);
        }
    }

    /**
     * 管理后台，给兼职人员重置密码
     *
     * @param id
     * @param newPassword
     * @throws ControllerException
     */
    @PreAuthorize("hasAnyAuthority('user:put/concurrent/password','user:post/concurrent/{id}/resetPassword')")
    @PutMapping(value = "/concurrent/{id}/password", params = {"newPassword"})
    @LogAnnotation(module = "employee-center", recordRequestParam = false)
    public void resetPassword(@PathVariable Long id, String newPassword) throws ControllerException {
        try {
            concurrentService.updatePassword(id, null, newPassword);
        } catch (ServiceException e) {
            throw new ControllerException(e);
        }
    }

    /**
     * 管理后台修改兼职人员
     *
     * @param sysUser
     * @throws JsonProcessingException
     */
    @PreAuthorize("hasAuthority('user:put/concurrent/me')")
    @PutMapping("/concurrent")
    @LogAnnotation(module = "employee-center", recordRequestParam = false)
    public void updateSysUser(@RequestBody SysUser sysUser) throws ControllerException {
        try {
            concurrentService.updateSysUser(sysUser);
        } catch (ServiceException e) {
            throw new ControllerException(e);
        }
    }

//    /**
//     * 管理后台给兼职人员分配角色
//     *
//     * @param id
//     * @param roleIds
//     * @throws JsonProcessingException
//     */
//    @PreAuthorize("hasAuthority('user:post/concurrent/{id}/roles')")
//    @PostMapping("/concurrent/{id}/roles")
//    @LogAnnotation(module = "employee-center", recordRequestParam = false)
//    public void setRoleToUser(@PathVariable Long id, @RequestBody Set<Long> roleIds) throws ControllerException {
//        try {
//            concurrentService.setRoleToUser(id, roleIds);
//        } catch (ServiceException e) {
//            throw new ControllerException(e);
//        }
//    }

//    /**
//     * 获取兼职人员的角色
//     *
//     * @param
//     * @return
//     * @throws ControllerException
//     */
//    @PreAuthorize("hasAnyAuthority('user:get/concurrent/{id}/roles')")
//    @GetMapping("/concurrent/{id}/roles")
//    @LogAnnotation(module = "employee-center", recordRequestParam = false)
//    public Set<SysRole> findRolesByUserId(@PathVariable Long id) throws ControllerException {
//        try {
//            return concurrentService.findRolesByUserId(id);
//        } catch (ServiceException e) {
//            throw new ControllerException(e);
//        }
//    }


    /**
     * 兼职人员查询
     * http://192.168.3.2:7000/concurrent?access_token=3b45d059-601b-4c63-85f9-9d77128ee94d&start=0&length=10
     * @param params //  searchKey=username, searchValue=as
     * @return
     * @throws ControllerException
     */
    @PreAuthorize("hasAuthority('user:get/concurrent')")
    @ApiOperation(value = "兼职人员查询列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "分页起始位置", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "limit", value = "分页结束位置", required = true, dataType = "Integer")
    })
    @GetMapping("/concurrent")
    @LogAnnotation(module = "employee-center", recordRequestParam = false)
    public PageResult<SysUser> findUsers(@RequestParam Map<String, Object> params) throws ControllerException {

        try {
            return concurrentService.findUsers(params);
        } catch (ServiceException e) {
            throw new ControllerException(e);
        }
    }

    /**
     * 修改自己的个人信息
     * @param sysUser
     * @return
     * @throws ControllerException
     */
    @PutMapping("/concurrent/me")
    @LogAnnotation(module = "employee-center", recordRequestParam = false)
    @PreAuthorize("hasAnyAuthority('user:put/users/me','user:post/users/saveOrUpdate')")
    public Result updateMe(@RequestBody SysUser sysUser) throws ControllerException {
//        SysUser user = SysUserUtil.getLoginAppUser();
//        sysUser.setId(user.getId());
        try {
            SysUser user = concurrentService.updateSysUser(sysUser);
            return Result.succeed(user, "操作成功");
        } catch (ServiceException e) {
            throw new ControllerException(e);
        }
    }

    /**
     * 修改密码
     * @param sysUser
     * @throws ControllerException
     */
    @PutMapping(value = "/concurrent/password")
    @PreAuthorize("hasAuthority('user:put/concurrent/password')")
    @LogAnnotation(module = "employee-center", recordRequestParam = false)
    public Result updatePassword(@RequestBody SysUser sysUser) throws ControllerException {
        try {
            if (StringUtils.isBlank(sysUser.getOldPassword())) {
                throw new IllegalArgumentException("旧密码不能为空");
            }
            if (StringUtils.isBlank(sysUser.getNewPassword())) {
                throw new IllegalArgumentException("新密码不能为空");
            }
            if (sysUser.getId() == 1277137734524300032L) {
                return Result.failed("超级管理员不给予修改");
            }
            return concurrentService.updatePassword(sysUser.getId(), sysUser.getOldPassword(), sysUser.getNewPassword());
        } catch (ServiceException e) {
            throw new ControllerException(e);
        }
    }

    /**
     * 修改兼职人员状态
     * @param params
     * @return
     * @throws ControllerException
     * @author gitgeek
     */
    @ApiOperation(value = "修改兼职人员状态")
    @GetMapping("/concurrent/updateEnabled")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "兼职人员id", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "enabled", value = "是否启用", required = true, dataType = "Boolean")
    })
    @LogAnnotation(module = "employee-center", recordRequestParam = false)
    @PreAuthorize("hasAnyAuthority('user:get/concurrent/updateEnabled' ,'user:put/concurrent/me')")
    public Result updateEnabled(@RequestParam Map<String, Object> params) throws ControllerException {
        try {
            Long id = MapUtils.getLong(params, "id");
            if (id == 1277137734524300032L) {
                return Result.failed("超级管理员不给予修改");
            }
            return concurrentService.updateEnabled(params);
        } catch (ServiceException e) {
            throw new ControllerException(e);
        }
    }

    /**
     * 管理后台，给兼职人员重置密码
     * @param id
     * @throws ControllerException
     * @author gitgeek
     */
    @PreAuthorize("hasAuthority('user:post/concurrent/{id}/resetPassword' )")
    @PostMapping(value = "/concurrent/{id}/resetPassword")
    @LogAnnotation(module = "employee-center", recordRequestParam = false)
    public Result resetPassword(@PathVariable Long id) throws ControllerException {
        try {
            if (id == 1277137734524300032L) {
                return Result.failed("超级管理员不给予修改");
            }
            concurrentService.updatePassword(id, null, "123456");
            return Result.succeed(null, "重置成功");
        } catch (ServiceException e) {
            throw new ControllerException(e);
        }
    }


    /**
     * 新增or更新
     * @param sysUser
     * @return
     * @throws ControllerException
     */
    @PostMapping("/concurrent/saveOrUpdate")
    @PreAuthorize("hasAnyAuthority('user:post/users/saveOrUpdate')")
    @LogAnnotation(module = "employee-center", recordRequestParam = false)
    public Result saveOrUpdate(@RequestBody SysUser sysUser) throws ControllerException {
        try {
            return concurrentService.saveOrUpdate(sysUser);
        } catch (ServiceException e) {
            throw new ControllerException(e);
        }
    }

    /**
     * 导出数据
     *
     * @return
     * @throws ControllerException
     */
    @PostMapping("/concurrent/exportUser")
    @PreAuthorize("hasAuthority('user:post/concurrent/exportUser')")
    public void exportUser(@RequestParam Map<String, Object> params, HttpServletRequest request, HttpServletResponse response) throws ControllerException {
        try {
            List<EmployeeModel> result = concurrentService.findAllUsers(params);
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-disposition", "attachment;filename=myExcel.xls");
            @Cleanup OutputStream ouputStream = null;
            Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("兼职人员导出", "兼职人员"),
                    EmployeeModel.class, result);
            ouputStream = response.getOutputStream();
            workbook.write(ouputStream);
        } catch (ServiceException e) {
            throw new ControllerException(e);
        } catch (IOException e) {
            throw new ControllerException(e);
        }

    }


    /**
     * 测试幂等接口
     * @param sysUser
     * @return
     * @throws ControllerException
     */
    @PostMapping("/concurrent/save")
    @ApiIdempotent
    public Result save(@RequestBody SysUser sysUser) throws ControllerException {
        try {
            return concurrentService.saveOrUpdate(sysUser);
        } catch (ServiceException e) {
            log.error("执行" + this.getClass().getSimpleName() + ":" + new Exception().getStackTrace()[0].getMethodName());
            throw new ControllerException(e);
        }
    }


}
